package JasPerl::PageContext::WrappedRequest;

use strict;
use warnings;

use parent qw(JasPerl::PSGI::RequestWrapper);

use JasPerl::Exceptions;
use JasPerl::RequestDispatcher;
use JasPerl::Util::Attributes;

my %DISPATCH_ATTRIBUTES = map { $_ => 1 } (
    JasPerl::RequestDispatcher::INCLUDE_REQUEST_URI,
    JasPerl::RequestDispatcher::INCLUDE_CONTEXT_PATH,
    JasPerl::RequestDispatcher::INCLUDE_SERVLET_PATH,
    JasPerl::RequestDispatcher::INCLUDE_PATH_INFO,
    JasPerl::RequestDispatcher::INCLUDE_QUERY_STRING,
    JasPerl::RequestDispatcher::FORWARD_REQUEST_URI,
    JasPerl::RequestDispatcher::FORWARD_CONTEXT_PATH,
    JasPerl::RequestDispatcher::FORWARD_SERVLET_PATH,
    JasPerl::RequestDispatcher::FORWARD_PATH_INFO,
    JasPerl::RequestDispatcher::FORWARD_QUERY_STRING
);

sub new {
    my ($class, $request, $uripath) = @_;

    return bless {
        request => $request,
        attributes => JasPerl::Util::Attributes->from($attributes)
    }, $class;
}

sub get_request {
    return $_[0]->{request};
}

sub get_attribute_names {
    my $self = shift;

    my %names = ( );
    @names{$self->{request}->get_attribute_names()->list()} = ( );
    @names{$self->{attributes}->get_attribute_names()->list()} = ( );
    return JasPerl::Util::Enumeratrion->from_list(keys %names);
}

sub get_attribute {
    my ($self, $name) = @_;
    JasPerl::Util::NullPointerException->throw()
        unless defined $name;
    if (exists $DISPATCH_ATTRIBUES{$name}) {
        return $self->{attributes}->get_attribute($name);
    } else {
        return $self->{request}->get_attribute($name);
    }
}

sub set_attribute {
    my ($self, $name, $value) = @_;
    JasPerl::Util::NullPointerException->throw()
        unless defined $name;
    if (exists $DISPATCH_ATTRIBUES{$name}) {
        return $self->{attributes}->set_attribute($name, $value);
    } else {
        return $self->{request}->set_attribute($name, $value);
    }
}

sub remove_attribute {
    my ($self, $name) = @_;
    JasPerl::Util::NullPointerException->throw()
        unless defined $name;
    if (exists $DISPATCH_ATTRIBUES{$name}) {
        return $self->{attributes}->remove_attribute($name);
    } else {
        return $self->{request}->remove_attribute($name);
    }
}

1;
